മെമ്മറി ചോർച്ച തടയുന്നതിനും കാര്യക്ഷമമായ സ്ട്രീം ശുചീകരണവും ഉറപ്പാക്കാൻ JavaScript അസിങ്ക് ജനറേറ്ററുകളിൽ വിഭവങ്ങൾ എങ്ങനെ കൈകാര്യം ചെയ്യാമെന്ന് പഠിക്കുക.
JavaScript Async ജനറേറ്റർ റിസോഴ്സ് മാനേജ്മെന്റ്: ശക്തമായ ആപ്ലിക്കേഷനുകൾക്കായി സ്ട്രീം റിസോഴ്സ് ക്ലീനപ്പ്
JavaScript-ൽ അസിൻക്രണസ് ഡാറ്റയുടെ സ്ട്രീമുകൾ കൈകാര്യം ചെയ്യുന്നതിനുള്ള ശക്തമായ സംവിധാനം നൽകുന്ന ഒന്നാണ് അസിൻക്രണസ് ജനറേറ്ററുകൾ (async generators). എന്നിരുന്നാലും, ഈ ജനറേറ്ററുകളിൽ വിഭവങ്ങൾ, പ്രത്യേകിച്ച് സ്ട്രീമുകൾ, ശരിയായി കൈകാര്യം ചെയ്യേണ്ടത് നിങ്ങളുടെ ആപ്ലിക്കേഷനുകളുടെ സ്ഥിരത ഉറപ്പാക്കാനും മെമ്മറി ലീക്കുകൾ തടയുന്നതിനും നിർണായകമാണ്. JavaScript അസിങ്ക് ജനറേറ്ററുകളിൽ റിസോഴ്സ് മാനേജ്മെൻ്റിനും സ്ട്രീം ക്ലീനപ്പിനുമുള്ള മികച്ച രീതികൾ ഈ സമഗ്രമായ ഗൈഡ് പര്യവേക്ഷണം ചെയ്യുന്നു, പ്രായോഗിക ഉദാഹരണങ്ങളും പ്രവർത്തനക്ഷമമായ ഉൾക്കാഴ്ചകളും വാഗ്ദാനം ചെയ്യുന്നു.
Async ജനറേറ്ററുകളെക്കുറിച്ച് മനസ്സിലാക്കുക
അസിൻക്രണസ് ജനറേറ്ററുകൾ എന്നാൽ താൽക്കാലികമായി നിർത്താനും പുനരാരംഭിക്കാനും കഴിയുന്ന ഫംഗ്ഷനുകളാണ്, ഇത് അവയെ അസിൻക്രണസായി മൂല്യങ്ങൾ നൽകാൻ അനുവദിക്കുന്നു. വലിയ ഡാറ്റാസെറ്റുകൾ പ്രോസസ്സ് ചെയ്യുന്നതിനും, API-കളിൽ നിന്ന് ഡാറ്റ സ്ട്രീം ചെയ്യുന്നതിനും, തത്സമയ ഇവന്റുകൾ കൈകാര്യം ചെയ്യുന്നതിനും ഇത് വളരെ അനുയോജ്യമാണ്.
async ജനറേറ്ററുകളുടെ പ്രധാന സവിശേഷതകൾ:
- അസിൻക്രണസ്: അവ
asyncകീവേഡ് ഉപയോഗിക്കുന്നു കൂടാതെawaitപ്രോമിസുകൾ ഉപയോഗിക്കാം. - 迭代器ಗಳು: അവ iterator പ്രോട്ടോക്കോൾ നടപ്പിലാക്കുന്നു, ഇത്
for await...ofലൂപ്പുകൾ ഉപയോഗിച്ച് ഉപയോഗിക്കാൻ അനുവദിക്കുന്നു. - വിളവ്: മൂല്യങ്ങൾ ഉൽപ്പാദിപ്പിക്കാൻ അവ
yieldകീവേഡ് ഉപയോഗിക്കുന്നു.
ഒരു ലളിതമായ async ജനറേറ്ററിൻ്റെ ഉദാഹരണം:
async function* generateNumbers(count) {
for (let i = 0; i < count; i++) {
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate asynchronous operation
yield i;
}
}
(async () => {
for await (const number of generateNumbers(5)) {
console.log(number);
}
})();
റിസോഴ്സ് മാനേജ്മെൻ്റിൻ്റെ പ്രാധാന്യം
async ജനറേറ്ററുകൾ ഉപയോഗിക്കുമ്പോൾ, പ്രത്യേകിച്ച് സ്ട്രീമുകളുമായി (ഉദാഹരണത്തിന്, ഒരു ഫയലിൽ നിന്ന് വായിക്കുക, ഒരു നെറ്റ്വർക്കിൽ നിന്ന് ഡാറ്റ കൊണ്ടുവരിക) പ്രവർത്തിക്കുമ്പോൾ, വിഭവങ്ങൾ ഫലപ്രദമായി കൈകാര്യം ചെയ്യേണ്ടത് അത്യാവശ്യമാണ്. ഇത് ചെയ്യാത്തത് താഴെ പറയുന്ന പ്രശ്നങ്ങളിലേക്ക് നയിച്ചേക്കാം:
- മെമ്മറി ചോർച്ച: സ്ട്രീമുകൾ ശരിയായി അടച്ചിട്ടില്ലെങ്കിൽ, അവ വിഭവങ്ങൾ നിലനിർത്തും, ഇത് മെമ്മറി ഉപഭോഗം വർദ്ധിപ്പിക്കുന്നതിനും ആപ്ലിക്കേഷൻ തകരാറിലാകാനും സാധ്യതയുണ്ട്.
- File Handle എക്സോസ്റ്റ്ഷൻ: ഫയൽ സ്ട്രീമുകൾ അടച്ചിട്ടില്ലെങ്കിൽ, ലഭ്യമായ ഫയൽ ഹാൻഡിലുകൾ ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിന് ഇല്ലാതാകാം.
- നെറ്റ്വർക്ക് കണക്ഷൻ പ്രശ്നങ്ങൾ: അടക്കാത്ത നെറ്റ്വർക്ക് കണക്ഷനുകൾ സെർവർ ഭാഗത്ത് വിഭവങ്ങളുടെ കുറവിനും ക്ലയിൻ്റ് ഭാഗത്ത് കണക്ഷൻ പരിധിക്കും കാരണമാകും.
- പ്രവചനാതീതമായ പെരുമാറ്റം: അപൂർണ്ണമായ അല്ലെങ്കിൽ തടസ്സപ്പെട്ട സ്ട്രീമുകൾ ആപ്ലിക്കേഷന്റെ അപ്രതീക്ഷിത പെരുമാറ്റത്തിനും ഡാറ്റാ വികലതക്കും കാരണമായേക്കാം.
ചിട്ടയായ റിസോഴ്സ് മാനേജ്മെൻ്റ്, സ്ട്രീമുകൾ ആവശ്യമില്ലാത്തപ്പോൾ അവ മര്യാദയോടെ അടയ്ക്കുകയും വിഭവങ്ങൾ റിലീസ് ചെയ്യുകയും ചെയ്യുന്നു.
സ്ട്രീം റിസോഴ്സ് ക്ലീനപ്പിനുള്ള ടെക്നിക്കുകൾ
JavaScript അസിങ്ക് ജനറേറ്ററുകളിൽ ശരിയായ സ്ട്രീം ക്ലീനപ്പ് ഉറപ്പാക്കാൻ നിരവധി സാങ്കേതിക വിദ്യകൾ ഉപയോഗിക്കാൻ കഴിയും:
1. ദി try...finally ബ്ലോക്ക്
ഒരു പിശക് സംഭവിച്ചാലും അല്ലെങ്കിൽ ജനറേറ്റർ സാധാരണയായി പൂർത്തിയായാലും ക്ലീനപ്പ് കോഡ് എപ്പോഴും എക്സിക്യൂട്ട് ചെയ്യപ്പെടുന്നു എന്ന് ഉറപ്പാക്കുന്നതിനുള്ള ഒരു അടിസ്ഥാന സംവിധാനമാണ് try...finally ബ്ലോക്ക്.
ഘടന:
async function* processStream(stream) {
try {
// Process the stream
while (true) {
const chunk = await stream.read();
if (!chunk) break;
yield processChunk(chunk);
}
} finally {
// Cleanup code: Close the stream
if (stream) {
await stream.close();
console.log('Stream closed.');
}
}
}
വിശദീകരണം:
tryബ്ലോക്കിൽ സ്ട്രീം പ്രോസസ്സ് ചെയ്യുന്ന കോഡ് അടങ്ങിയിരിക്കുന്നു.finallyബ്ലോക്കിൽ ക്ലീനപ്പ് കോഡ് അടങ്ങിയിരിക്കുന്നു, ഇത്tryബ്ലോക്ക് വിജയകരമായി പൂർത്തിയായാലും അല്ലെങ്കിൽ ഒരു പിശക് സംഭവിച്ചാലും എക്സിക്യൂട്ട് ചെയ്യപ്പെടുന്നു.stream.close()രീതി സ്ട്രീം അടയ്ക്കാനും വിഭവങ്ങൾ റിലീസ് ചെയ്യാനും വിളിക്കുന്നു. ജനറേറ്റർ പുറത്തുകടക്കുന്നതിന് മുമ്പ് ഇത് പൂർത്തിയാകുമെന്ന് ഉറപ്പാക്കാൻ ഇത് `awaited` ആണ്.
Node.js ഫയൽ സ്ട്രീമിൻ്റെ ഉദാഹരണം:
const fs = require('fs');
const { Readable } = require('stream');
async function* processFile(filePath) {
let fileStream;
try {
fileStream = fs.createReadStream(filePath);
for await (const chunk of fileStream) {
yield chunk.toString();
}
} finally {
if (fileStream) {
fileStream.close(); // Use close for streams created by fs
console.log('File stream closed.');
}
}
}
(async () => {
const filePath = 'example.txt'; // Replace with your file path
fs.writeFileSync(filePath, 'This is some example content.\nWith multiple lines.\nTo demonstrate stream processing.');
for await (const line of processFile(filePath)) {
console.log(line);
}
})();
പ്രധാന പരിഗണനകൾ:
- സ്ട്രീം ഇതുവരെ ആരംഭിച്ചിട്ടില്ലെങ്കിൽ, പിശകുകൾ ഒഴിവാക്കാൻ അടയ്ക്കാൻ ശ്രമിക്കുന്നതിന് മുമ്പ് സ്ട്രീം നിലവിലുണ്ടോയെന്ന് പരിശോധിക്കുക.
- ജനറേറ്റർ പുറത്തുകടക്കുന്നതിന് മുമ്പ് സ്ട്രീം പൂർണ്ണമായി അടച്ചിട്ടുണ്ടെന്ന് ഉറപ്പാക്കാൻ
close()രീതി കാത്തിരിക്കുന്നു എന്ന് ഉറപ്പാക്കുക. പല സ്ട്രീം നടപ്പിലാക്കലുകളും അസിൻക്രണസ് ആണ്.
2. റിസോഴ്സ് അലോക്കേഷനും ക്ലീനപ്പുമുള്ള ഒരു റാപ്പർ ഫംഗ്ഷൻ ഉപയോഗിക്കുന്നു
റിസോഴ്സ് അലോക്കേഷനും ക്ലീനപ്പ് ലോജിക്കും ഒരു റാപ്പർ ഫംഗ്ഷനുള്ളിൽ ഉൾപ്പെടുത്തുക എന്നതാണ് മറ്റൊരു സമീപനം. ഇത് കോഡ് വീണ്ടും ഉപയോഗിക്കുന്നതിന് പ്രോത്സാഹിപ്പിക്കുകയും ജനറേറ്റർ കോഡ് ലളിതമാക്കുകയും ചെയ്യുന്നു.
async function withResource(resourceFactory, generatorFunction) {
let resource;
try {
resource = await resourceFactory();
for await (const value of generatorFunction(resource)) {
yield value;
}
} finally {
if (resource) {
await resource.cleanup();
console.log('Resource cleaned up.');
}
}
}
വിശദീകരണം:
resourceFactory: റിസോഴ്സ് (ഉദാഹരണത്തിന്, ഒരു സ്ട്രീം) സൃഷ്ടിക്കുകയും തിരികെ നൽകുകയും ചെയ്യുന്ന ഒരു ഫംഗ്ഷൻ.generatorFunction: റിസോഴ്സ് ഉപയോഗിക്കുന്ന ഒരു async ജനറേറ്റർ ഫംഗ്ഷൻ.withResourceഫംഗ്ഷൻ റിസോഴ്സ് ലൈഫ് സൈക്കിൾ കൈകാര്യം ചെയ്യുന്നു, ഇത് സൃഷ്ടിക്കപ്പെടുന്നു, ജനറേറ്റർ ഉപയോഗിക്കുന്നു, തുടർന്ന്finallyബ്ലോക്കിൽ ക്ലീൻ അപ്പ് ചെയ്യുന്നു എന്ന് ഉറപ്പാക്കുന്നു.
ഒരു ഇഷ്ടമുള്ള സ്ട്രീം ക്ലാസ് ഉപയോഗിക്കുന്നതിനുള്ള ഉദാഹരണം:
class CustomStream {
constructor() {
this.data = ['Line 1', 'Line 2', 'Line 3'];
this.index = 0;
}
async read() {
await new Promise(resolve => setTimeout(resolve, 50)); // Simulate async read
if (this.index < this.data.length) {
return this.data[this.index++];
} else {
return null;
}
}
async cleanup() {
console.log('CustomStream cleanup completed.');
}
}
async function* processCustomStream(stream) {
while (true) {
const chunk = await stream.read();
if (!chunk) break;
yield `Processed: ${chunk}`;
}
}
async function withResource(resourceFactory, generatorFunction) {
let resource;
try {
resource = await resourceFactory();
for await (const value of generatorFunction(resource)) {
yield value;
}
} finally {
if (resource && resource.cleanup) {
await resource.cleanup();
console.log('Resource cleaned up.');
}
}
}
(async () => {
for await (const line of withResource(() => new CustomStream(), processCustomStream)) {
console.log(line);
}
})();
3. AbortController ഉപയോഗപ്പെടുത്തുന്നു
AbortController എന്നത് ബിൽറ്റ്-ഇൻ JavaScript API ആണ്, ഇത് സ്ട്രീം പ്രോസസ്സിംഗ് ഉൾപ്പെടെയുള്ള അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ റദ്ദാക്കാൻ സിഗ്നൽ ചെയ്യാൻ നിങ്ങളെ അനുവദിക്കുന്നു. ടൈം outs, ഉപയോക്തൃ റദ്ദാക്കലുകൾ അല്ലെങ്കിൽ ഒരു സ്ട്രീമിനെ അകാലത്തിൽ അവസാനിപ്പിക്കേണ്ട മറ്റ് സാഹചര്യങ്ങൾ എന്നിവ കൈകാര്യം ചെയ്യാൻ ഇത് പ്രത്യേകിച്ചും ഉപയോഗപ്രദമാണ്.
async function* processStreamWithAbort(stream, signal) {
try {
while (!signal.aborted) {
const chunk = await stream.read();
if (!chunk) break;
yield processChunk(chunk);
}
} finally {
if (stream) {
await stream.close();
console.log('Stream closed.');
}
}
}
(async () => {
const controller = new AbortController();
const { signal } = controller;
// Simulate a timeout
setTimeout(() => {
console.log('Aborting stream processing...');
controller.abort();
}, 2000);
const stream = createSomeStream(); // Replace with your stream creation logic
try {
for await (const chunk of processStreamWithAbort(stream, signal)) {
console.log('Chunk:', chunk);
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('Stream processing aborted.');
} else {
console.error('Error processing stream:', error);
}
}
})();
വിശദീകരണം:
- ഒരു
AbortControllerസൃഷ്ടിക്കപ്പെടുന്നു, അതിന്റെsignalജനറേറ്റർ ഫംഗ്ഷനിലേക്ക് കൈമാറുന്നു. - ഓരോ ഇറ്ററേഷനിലും പ്രവർത്തനം റദ്ദാക്കിയോ എന്ന് നിർണ്ണയിക്കാൻ ജനറേറ്റർ
signal.abortedപ്രോപ്പർട്ടി പരിശോധിക്കുന്നു. - സിഗ്നൽ റദ്ദാക്കിയാൽ, ലൂപ്പ് തകരുന്നു, സ്ട്രീം അടയ്ക്കാൻ
finallyബ്ലോക്ക് എക്സിക്യൂട്ട് ചെയ്യപ്പെടുന്നു. - ഓപ്പറേഷൻ റദ്ദാക്കാൻ
controller.abort()രീതി ഉപയോഗിക്കുന്നു.
AbortController ഉപയോഗിക്കുന്നതിൻ്റെ പ്രയോജനങ്ങൾ:
- അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ റദ്ദാക്കാൻ ഒരു സ്റ്റാൻഡേർഡ് മാർഗ്ഗം നൽകുന്നു.
- സ്ട്രീം പ്രോസസ്സിംഗിൻ്റെ വ്യക്തവും പ്രവചിക്കാവുന്നതുമായ റദ്ദാക്കലിന് അനുവദിക്കുന്നു.
AbortSignalപിന്തുണയ്ക്കുന്ന മറ്റ് അസിൻക്രണസ് API-കളുമായി നന്നായി സംയോജിപ്പിക്കുന്നു.
4. സ്ട്രീം പ്രോസസ്സിംഗിനിടയിലുള്ള പിശകുകൾ കൈകാര്യം ചെയ്യുക
നെറ്റ്വർക്ക് പിശകുകൾ, ഫയൽ ആക്സസ് പിശകുകൾ അല്ലെങ്കിൽ ഡാറ്റാ പാഴ്സിംഗ് പിശകുകൾ എന്നിങ്ങനെ സ്ട്രീം പ്രോസസ്സിംഗിനിടയിൽ പിശകുകൾ സംഭവിക്കാം. ജനറേറ്റർ തകരാറിലാകാതിരിക്കാനും വിഭവങ്ങൾ ശരിയായി ക്ലീൻ അപ്പ് ചെയ്യാനും ഈ പിശകുകൾ നന്നായി കൈകാര്യം ചെയ്യേണ്ടത് അത്യാവശ്യമാണ്.
async function* processStreamWithErrorHandling(stream) {
try {
while (true) {
try {
const chunk = await stream.read();
if (!chunk) break;
yield processChunk(chunk);
} catch (error) {
console.error('Error processing chunk:', error);
// Optionally, you can choose to re-throw the error or continue processing
// throw error;
}
}
} finally {
if (stream) {
try {
await stream.close();
console.log('Stream closed.');
} catch (closeError) {
console.error('Error closing stream:', closeError);
}
}
}
}
വിശദീകരണം:
- പ്രത്യേക ഭാഗങ്ങൾ വായിക്കുമ്പോഴും പ്രോസസ്സ് ചെയ്യുമ്പോഴും സംഭവിക്കുന്ന പിശകുകൾ കൈകാര്യം ചെയ്യാൻ ഒരു നെസ്റ്റഡ്
try...catchബ്ലോക്ക് ഉപയോഗിക്കുന്നു. catchബ്ലോക്ക് പിശക് ലോഗ് ചെയ്യുന്നു കൂടാതെ ഓപ്ഷണലായി പിശക് വീണ്ടും എറിയാനോ പ്രോസസ്സിംഗ് തുടരാനോ നിങ്ങളെ അനുവദിക്കുന്നു.- സ്ട്രീം ക്ലോസ് ചെയ്യുമ്പോൾ സംഭവിക്കാനിടയുള്ള പിശകുകൾ കൈകാര്യം ചെയ്യാൻ
finallyബ്ലോക്കിൽ ഒരുtry...catchബ്ലോക്ക് ഉൾപ്പെടുന്നു. ക്ലോസ് ചെയ്യുമ്പോൾ ഉണ്ടാകുന്ന പിശകുകൾ ജനറേറ്ററിനെ പുറത്തുകടക്കുന്നതിൽ നിന്ന് തടയുന്നില്ലെന്ന് ഇത് ഉറപ്പാക്കുന്നു.
5. സ്ട്രീം മാനേജ്മെൻ്റിനായുള്ള ലൈബ്രറികൾ പ്രയോജനപ്പെടുത്തുക
സ്ട്രീം മാനേജ്മെൻ്റും റിസോഴ്സ് ക്ലീനപ്പും ലളിതമാക്കുന്നതിനുള്ള യൂട്ടിലിറ്റികൾ നൽകുന്ന നിരവധി JavaScript ലൈബ്രറികൾ ഉണ്ട്. ഈ ലൈബ്രറികൾക്ക് ബോയിലർപ്ലേറ്റ് കോഡ് കുറയ്ക്കാനും നിങ്ങളുടെ ആപ്ലിക്കേഷനുകളുടെ വിശ്വാസ്യത മെച്ചപ്പെടുത്താനും കഴിയും.
ഉദാഹരണങ്ങൾ:
- `node-cleanup` (Node.js): പ്രോസസ്സ് എക്സിറ്റ് ചെയ്യുമ്പോൾ എക്സിക്യൂട്ട് ചെയ്യുന്ന ക്ലീനപ്പ് ഹാൻഡ്ലറുകൾ രജിസ്റ്റർ ചെയ്യാൻ ഈ ലൈബ്രറി ലളിതമായൊരു വഴി നൽകുന്നു.
- `rxjs` (JavaScript-നുള്ള പ്രതികരണ വിപുലീകരണങ്ങൾ): അസിൻക്രണസ് ഡാറ്റാ സ്ട്രീമുകൾ കൈകാര്യം ചെയ്യുന്നതിനും വിഭവങ്ങൾ കൈകാര്യം ചെയ്യുന്നതിനും പിശകുകൾ കൈകാര്യം ചെയ്യുന്നതിനും ഓപ്പറേറ്റർമാരെ ഉൾപ്പെടെ ശക്തമായ ഒരു അമൂർത്തീകരണം RxJS നൽകുന്നു.
- ` Highland.js` (Highland): സ്ട്രീമുകളിലേക്ക് കൂടുതൽ സങ്കീർണ്ണമായ കാര്യങ്ങൾ ചെയ്യണമെങ്കിൽ Highland ഒരു സ്ട്രീമിംഗ് ലൈബ്രറിയാണ്.
`node-cleanup` ഉപയോഗിക്കുന്നു (Node.js):
const fs = require('fs');
const cleanup = require('node-cleanup');
async function* processFile(filePath) {
let fileStream;
try {
fileStream = fs.createReadStream(filePath);
for await (const chunk of fileStream) {
yield chunk.toString();
}
} finally {
//This might not always work since the process might terminate abruptly.
//Using try...finally in the generator itself is preferable.
}
}
(async () => {
const filePath = 'example.txt'; // Replace with your file path
fs.writeFileSync(filePath, 'This is some example content.\nWith multiple lines.\nTo demonstrate stream processing.');
const stream = processFile(filePath);
let fileStream = fs.createReadStream(filePath);
cleanup(function (exitCode, signal) {
// cleanup files, delete database entries, etc
fileStream.close();
console.log('File stream closed by node-cleanup.');
cleanup.uninstall(); //Uncomment to prevent calling this callback again (more info below)
return false;
});
for await (const line of stream) {
console.log(line);
}
})();
പ്രായോഗിക ഉദാഹരണങ്ങളും സാഹചര്യങ്ങളും
1. ഒരു ഡാറ്റാബേസിൽ നിന്ന് ഡാറ്റ സ്ട്രീം ചെയ്യുന്നു
ഒരു ഡാറ്റാബേസിൽ നിന്ന് ഡാറ്റ സ്ട്രീം ചെയ്യുമ്പോൾ, സ്ട്രീം പ്രോസസ്സ് ചെയ്ത ശേഷം ഡാറ്റാബേസ് കണക്ഷൻ അടയ്ക്കുന്നത് അത്യാവശ്യമാണ്.
const { Pool } = require('pg');
async function* streamDataFromDatabase(query) {
const pool = new Pool({ /* connection details */ });
let client;
try {
client = await pool.connect();
const result = await client.query(query);
for (const row of result.rows) {
yield row;
}
} finally {
if (client) {
client.release(); // Release the client back to the pool
console.log('Database connection released.');
}
await pool.end(); // Close the pool
console.log('Database pool closed.');
}
}
(async () => {
for await (const row of streamDataFromDatabase('SELECT * FROM users')) {
console.log(row);
}
})();
2. വലിയ CSV ഫയലുകൾ പ്രോസസ്സ് ചെയ്യുന്നു
വലിയ CSV ഫയലുകൾ പ്രോസസ്സ് ചെയ്യുമ്പോൾ, മെമ്മറി ചോർച്ച ഒഴിവാക്കാൻ ഓരോ വരിയും പ്രോസസ്സ് ചെയ്ത ശേഷം ഫയൽ സ്ട്രീം അടയ്ക്കുന്നത് പ്രധാനമാണ്.
const fs = require('fs');
const csv = require('csv-parser');
async function* processCsvFile(filePath) {
let fileStream;
try {
fileStream = fs.createReadStream(filePath);
const parser = csv();
fileStream.pipe(parser);
for await (const row of parser) {
yield row;
}
} finally {
if (fileStream) {
fileStream.close(); // Properly closes the stream
console.log('CSV file stream closed.');
}
}
}
(async () => {
const filePath = 'data.csv'; // Replace with your CSV file path
fs.writeFileSync(filePath, 'header1,header2\nvalue1,value2\nvalue3,value4');
for await (const row of processCsvFile(filePath)) {
console.log(row);
}
})();
3. ഒരു API-യിൽ നിന്ന് ഡാറ്റ സ്ട്രീം ചെയ്യുന്നു
ഒരു API-യിൽ നിന്ന് ഡാറ്റ സ്ട്രീം ചെയ്യുമ്പോൾ, സ്ട്രീം പ്രോസസ്സ് ചെയ്ത ശേഷം നെറ്റ്വർക്ക് കണക്ഷൻ അടയ്ക്കുന്നത് നിർണായകമാണ്.
const https = require('https');
async function* streamDataFromApi(url) {
let responseStream;
try {
const promise = new Promise((resolve, reject) => {
https.get(url, (res) => {
responseStream = res;
res.on('data', (chunk) => {
resolve(chunk.toString());
});
res.on('end', () => {
resolve(null);
});
res.on('error', (error) => {
reject(error);
});
}).on('error', (error) => {
reject(error);
});
});
while(true) {
const chunk = await promise; //Await the promise, it returns a chunk.
if (!chunk) break;
yield chunk;
}
} finally {
if (responseStream && typeof responseStream.destroy === 'function') { // Check if destroy exists for safety.
responseStream.destroy();
console.log('API stream destroyed.');
}
}
}
(async () => {
// Use a public API that returns streamable data (e.g., a large JSON file)
const apiUrl = 'https://jsonplaceholder.typicode.com/todos/1';
for await (const chunk of streamDataFromApi(apiUrl)) {
console.log('Chunk:', chunk);
}
})();
ശക്തമായ റിസോഴ്സ് മാനേജ്മെൻ്റിനുള്ള മികച്ച രീതികൾ
JavaScript അസിങ്ക് ജനറേറ്ററുകളിൽ ശക്തമായ റിസോഴ്സ് മാനേജ്മെൻ്റ് ഉറപ്പാക്കാൻ, ഈ മികച്ച രീതികൾ പാലിക്കുക:
- ഒരു പിശക് സംഭവിച്ചാലും അല്ലെങ്കിൽ ജനറേറ്റർ സാധാരണയായി പൂർത്തിയായാലും ക്ലീനപ്പ് കോഡ് എക്സിക്യൂട്ട് ചെയ്യാൻ എപ്പോഴും
try...finallyബ്ലോക്കുകൾ ഉപയോഗിക്കുക. - വിഭവം ഇതുവരെ ആരംഭിച്ചിട്ടില്ലെങ്കിൽ, പിശകുകൾ ഒഴിവാക്കാൻ അവ അടയ്ക്കാൻ ശ്രമിക്കുന്നതിന് മുമ്പ് വിഭവങ്ങൾ നിലവിലുണ്ടോയെന്ന് പരിശോധിക്കുക.
- ജനറേറ്റർ പുറത്തുകടക്കുന്നതിന് മുമ്പ് വിഭവങ്ങൾ പൂർണ്ണമായി അടച്ചിട്ടുണ്ടെന്ന് ഉറപ്പാക്കാൻ അസിൻക്രണസ്
close()രീതികൾ കാത്തിരിക്കുക. - ജനറേറ്റർ തകരാറിലാകാതിരിക്കാനും വിഭവങ്ങൾ ശരിയായി ക്ലീൻ അപ്പ് ചെയ്യാനും പിശകുകൾ നന്നായി കൈകാര്യം ചെയ്യുക.
- കോഡ് വീണ്ടും ഉപയോഗിക്കുന്നതിനും ജനറേറ്റർ കോഡ് ലളിതമാക്കുന്നതിനും റിസോഴ്സ് അലോക്കേഷനും ക്ലീനപ്പ് ലോജിക്കും റാപ്പർ ഫംഗ്ഷനുകൾ ഉപയോഗിക്കുക.
- അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ റദ്ദാക്കാനും സ്ട്രീം പ്രോസസ്സിംഗിൻ്റെ ക്ലീൻ റദ്ദാക്കൽ ഉറപ്പാക്കാനും
AbortControllerഉപയോഗപ്പെടുത്തുക. - ബോയിലർപ്ലേറ്റ് കോഡ് കുറക്കുന്നതിനും നിങ്ങളുടെ ആപ്ലിക്കേഷനുകളുടെ വിശ്വാസ്യത മെച്ചപ്പെടുത്തുന്നതിനും സ്ട്രീം മാനേജ്മെൻ്റിനായി ലൈബ്രറികൾ പ്രയോജനപ്പെടുത്തുക.
- ഏത് വിഭവങ്ങളാണ് ക്ലീൻ അപ്പ് ചെയ്യേണ്ടതെന്നും എങ്ങനെ ചെയ്യണമെന്നും വ്യക്തമാക്കാൻ നിങ്ങളുടെ കോഡ് രേഖപ്പെടുത്തുക.
- പിശക് സാഹചര്യങ്ങളും റദ്ദാക്കലുകളും ഉൾപ്പെടെ വിവിധ സാഹചര്യങ്ങളിൽ വിഭവങ്ങൾ ശരിയായി ക്ലീൻ അപ്പ് ചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കാൻ നിങ്ങളുടെ കോഡ് നന്നായി പരീക്ഷിക്കുക.
ഉപസംഹാരം
അസിങ്ക് ജനറേറ്ററുകൾ ഉപയോഗിക്കുന്ന ശക്തവും വിശ്വസനീയവുമായ JavaScript ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിന് ശരിയായ റിസോഴ്സ് മാനേജ്മെൻ്റ് അത്യാവശ്യമാണ്. ഈ ഗൈഡിൽ നൽകിയിട്ടുള്ള ടെക്നിക്കുകളും മികച്ച രീതികളും പിന്തുടരുന്നതിലൂടെ, നിങ്ങൾക്ക് മെമ്മറി ചോർച്ച തടയാനും, കാര്യക്ഷമമായ സ്ട്രീം ക്ലീനപ്പ് ഉറപ്പാക്കാനും, പിശകുകൾക്കും, അപ്രതീക്ഷിത സംഭവങ്ങൾക്കും പ്രതിരോധശേഷിയുള്ള ആപ്ലിക്കേഷനുകൾ സൃഷ്ടിക്കാനും കഴിയും. ഈ രീതികൾ സ്വീകരിക്കുന്നതിലൂടെ, ഡെവലപ്പർമാർക്ക് അവരുടെ JavaScript ആപ്ലിക്കേഷനുകളുടെ സ്ഥിരതയും സ്കേലബിളിറ്റിയും, പ്രത്യേകിച്ച് സ്ട്രീമിംഗ് ഡാറ്റയോ അല്ലെങ്കിൽ അസിൻക്രണസ് പ്രവർത്തനങ്ങളോ കൈകാര്യം ചെയ്യുന്ന ആപ്ലിക്കേഷനുകളിൽ വളരെയധികം മെച്ചപ്പെടുത്താൻ കഴിയും. വികസന പ്രക്രിയയുടെ തുടക്കത്തിൽ തന്നെ സാധ്യമായ പ്രശ്നങ്ങൾ കണ്ടെത്താൻ എപ്പോഴും റിസോഴ്സ് ക്ലീനപ്പ് നന്നായി പരീക്ഷിക്കാൻ ഓർമ്മിക്കുക.